package hh.util.time;

import hh.util.Log;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.Date;


/**
 * 数组放置从1970年开始所有年份的起始毫秒值，输入一个毫秒，通过二分查找
 *
 * @author huanghuai
 * @date 2020/10/12
 */
@Slf4j
public class BinarySearchCalender extends MyCalender {

    public static void main(String[] args) {
        new BinarySearchCalender();
        System.out.println();
        int ms = 0;
        long[] arr = new long[12];
        for (int i = 1; i < 12; i++) {
            arr[i] = (leapMonthCache[i - 1] * TimeUtil.DAY_MS + arr[i - 1]);
        }
        System.out.println(Arrays.toString(arr));
        for (int i = 1; i < 12; i++) {
            arr[i] = (monthCache[i - 1] * TimeUtil.DAY_MS + arr[i - 1]);
        }
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 默认缓存1970年正负200年的数据   1770 - 2170
     */
    private final int defaultYearLimit = 1000;
    private final int[] yearCache = new int[defaultYearLimit * 2 + 1];
    private final long[] yearMsCache = new long[defaultYearLimit * 2 + 1];
    private static final long[] leapMonthMsCache = {0, 2678400000L, 5184000000L, 7862400000L, 10454400000L, 13132800000L,
            15724800000L, 18403200000L, 21081600000L, 23673600000L, 26352000000L, 28944000000L};
    private static final int[] leapMonthCache = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    private static final long[] monthMsCache = {0, 2678400000L, 5097600000L, 7776000000L, 10368000000L, 13046400000L,
            15638400000L, 18316800000L, 20995200000L, 23587200000L, 26265600000L, 28857600000L};
    private static final int[] monthCache = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    {
        int rawOffset = TIME_ZONE.getRawOffset();
        int metaYearIdx = yearCache.length >> 1;
        yearCache[metaYearIdx] = 1970;
        // 1970-1-1 00:00:00 格林威治是0毫秒   但是东八区的1970-1-1 00:00:00是 -28800000毫秒（8小时） 所以需要减去rawOffset
        yearMsCache[metaYearIdx] = 0 - rawOffset;

        long nextMs = yearMsCache[metaYearIdx];
        for (int i = metaYearIdx - 1; i >= 0; i--) {
            int year = yearCache[i + 1] - 1;
            nextMs -= TimeUtil.getDays(year) * TimeUtil.DAY_MS;
            yearCache[i] = year;
            yearMsCache[i] = nextMs;
        }

        nextMs = yearMsCache[metaYearIdx];
        for (int i = metaYearIdx + 1; i < yearCache.length; i++) {
            int lastYear = yearCache[i - 1];
            nextMs += TimeUtil.getDays(lastYear) * TimeUtil.DAY_MS;
            yearCache[i] = lastYear + 1;
            yearMsCache[i] = nextMs;
        }
        log.debug("\n" + Arrays.toString(yearCache) + "\n" + Arrays.toString(yearMsCache));
    }


    @Override
    protected Year getYear(long ms) {
        int years = (int) (ms / TimeUtil.ORDINARY_YEAR_DAYS_MS);
        for (int i = years; i >= 0; i--) {
            // 毫秒值在上一年和当前年之间，取当前年
            if (ms < yearMsCache[i + 1] && ms >= yearMsCache[i]) {
                // return yearCache[i];
            }
        }

        return super.getYear(ms);
    }

    @Override
    protected Month getMonth(boolean leap, long monthMs) {
        return super.getMonth(leap, monthMs);
    }

    @Override
    protected Day getDay(long ms) {
        long years = ms / TimeUtil.ORDINARY_YEAR_DAYS_MS;
        long months = (ms = ms % TimeUtil.ORDINARY_YEAR_DAYS_MS) / 28 / TimeUtil.DAY_MS;
        long hour = (ms = ms % TimeUtil.DAY_MS) / TimeUtil.HOUR_MS;
        long min = (ms = ms % TimeUtil.HOUR_MS) / 60;
        long second = (ms = ms % TimeUtil.MINUTE_MS) / 60;
        long millis = ms % TimeUtil.SECOND_MS;
        return null;

    }

    @Override
    public int year(Date date) {
        return super.year(date);
    }

    @Override
    public int year(long ms) {
        return super.year(ms);
    }

    @Override
    public String yearMonth(long ms) {
        return super.yearMonth(ms);
    }

    @Override
    public String yearMonthDay(long ms) {
        return super.yearMonthDay(ms);
    }

    @Override
    public String yearMonth(Date date) {
        return super.yearMonth(date);
    }
}
